<html>
<head><meta charset="utf-8"><title>Rewrite `Call(clone, _N)` to `Copy(*_N)`? · t-compiler/wg-mir-opt · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/index.html">t-compiler/wg-mir-opt</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Rewrite.20.60Call(clone.2C.20_N).60.20to.20.60Copy(*_N).60.3F.html">Rewrite `Call(clone, _N)` to `Copy(*_N)`?</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="209852212"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Rewrite%20%60Call%28clone%2C%20_N%29%60%20to%20%60Copy%28%2A_N%29%60%3F/near/209852212" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Rewrite.20.60Call(clone.2C.20_N).60.20to.20.60Copy(*_N).60.3F.html#209852212">(Sep 12 2020 at 01:15)</a>:</h4>
<p>An idea inspired by <a href="https://github.com/rust-lang/rust/issues/76552">#76552</a>: <a href="https://rust-lang.github.io/rfcs/1521-copy-clone-semantics.html">https://rust-lang.github.io/rfcs/1521-copy-clone-semantics.html</a> says that it's fine to bitcopy instead of <code>Clone::clone</code> for <code>T: Copy</code>.  Could we just do that as a mir-opt?  It feels plausible that we could do it faster than LLVM can do it via inlining, and would save our eventual inlining pass from needing to do it.  (And, for deeper <code>derive(Clone)</code>s, saves needing to figure out that it's a field-by-field copy before combining the <code>memcpy</code>.)  It's also that many fewer BBs (after simplifycfg) and unwind edges.</p>
<p>I guess it would work best post-monomorphization, where IIRC we don't run anything, but if nothing else it ought to help out <code>derive(Clone)</code> on anything with a <code>Copy</code> field, which seems pretty common -- <code>usize</code>, every <code>&amp;_</code>, ...</p>
<p>Demonstration that even for <code>usize</code> fields we currently have <code>clone</code> calls in the optimized MIR: <a href="https://rust.godbolt.org/z/be4Eqn">https://rust.godbolt.org/z/be4Eqn</a></p>
<p>cc <span class="user-mention" data-user-id="324038">@ridiculous_fish</span></p>



<a name="209853665"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Rewrite%20%60Call%28clone%2C%20_N%29%60%20to%20%60Copy%28%2A_N%29%60%3F/near/209853665" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Rewrite.20.60Call(clone.2C.20_N).60.20to.20.60Copy(*_N).60.3F.html#209853665">(Sep 12 2020 at 01:58)</a>:</h4>
<p>Ideally we'd do this for T: CouldBeCopy with derived clones I think, though that does go a bit beyond the RFC, otherwise it doesn't apply to Range etc</p>



<a name="209863901"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Rewrite%20%60Call%28clone%2C%20_N%29%60%20to%20%60Copy%28%2A_N%29%60%3F/near/209863901" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Rewrite.20.60Call(clone.2C.20_N).60.20to.20.60Copy(*_N).60.3F.html#209863901">(Sep 12 2020 at 04:28)</a>:</h4>
<p>Yeah, what I proposed there wouldn't actually solve the mentioned issue, it just inspired it.  Just wanted to drop the idea here before implementing in case the response was "no, that's disallowed because _________" or "that'll be covered by _______ that's already being worked on".</p>
<p>(But as you imply, I guess we could add <code>marker::StructuralClone</code> and check on that instead...)</p>



<a name="209877723"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Rewrite%20%60Call%28clone%2C%20_N%29%60%20to%20%60Copy%28%2A_N%29%60%3F/near/209877723" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Rewrite.20.60Call(clone.2C.20_N).60.20to.20.60Copy(*_N).60.3F.html#209877723">(Sep 12 2020 at 11:43)</a>:</h4>
<p>We'd need it to have more auto-trait behavior I think. I've long been tempted to remove the code generation from the built-in derives and instead call an intrinsic - there's a lot of similar things to this afaik. For example you could partialeq via memcmp instead of recursively calling it on every field</p>



<a name="209877732"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Rewrite%20%60Call%28clone%2C%20_N%29%60%20to%20%60Copy%28%2A_N%29%60%3F/near/209877732" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Rewrite.20.60Call(clone.2C.20_N).60.20to.20.60Copy(*_N).60.3F.html#209877732">(Sep 12 2020 at 11:43)</a>:</h4>
<p>That is, directly generate MIR for them</p>



<a name="209877864"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Rewrite%20%60Call%28clone%2C%20_N%29%60%20to%20%60Copy%28%2A_N%29%60%3F/near/209877864" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jannis Harder <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Rewrite.20.60Call(clone.2C.20_N).60.20to.20.60Copy(*_N).60.3F.html#209877864">(Sep 12 2020 at 11:47)</a>:</h4>
<p><span class="user-mention silent" data-user-id="116122">simulacrum</span> <a href="#narrow/stream/189540-t-compiler.2Fwg-mir-opt/topic/Rewrite.20.60Call(clone.2C.20_N).60.20to.20.60Copy(*_N).60.3F/near/209877723">said</a>:</p>
<blockquote>
<p>We'd need it to have more auto-trait behavior I think. I've long been tempted to remove the code generation from the built-in derives and instead call an intrinsic - there's a lot of similar things to this afaik. For example you could partialeq via memcmp instead of recursively calling it on every field</p>
</blockquote>
<p>I haven't rechecked in the past year, but in my SAT solver I had to transmute <code>Option&lt;bool&gt;</code> into <code>u8</code> for equality comparison because it would generate (rather unpredictable) branches for every == in the inner loop otherwise.</p>



<a name="209878086"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Rewrite%20%60Call%28clone%2C%20_N%29%60%20to%20%60Copy%28%2A_N%29%60%3F/near/209878086" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Rewrite.20.60Call(clone.2C.20_N).60.20to.20.60Copy(*_N).60.3F.html#209878086">(Sep 12 2020 at 11:53)</a>:</h4>
<p>Yep, this is definitely one case where this transform absolutely makes sense but is impossible for a derive macro to detect. I sort of doubt we can have a peephole opt for it too</p>



<a name="209896796"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/Rewrite%20%60Call%28clone%2C%20_N%29%60%20to%20%60Copy%28%2A_N%29%60%3F/near/209896796" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/Rewrite.20.60Call(clone.2C.20_N).60.20to.20.60Copy(*_N).60.3F.html#209896796">(Sep 12 2020 at 19:43)</a>:</h4>
<p>Agreed -- we've seen from the attempts at making result match-and-rebuild a no-op that it's awkward doing these things across blocks.</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>